
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import tanling.matplot_4j.d3d.facade.MatPlot3DMgr;

public class BarsMoveDemo {

	// 数据组数量
	static int count = 5;

	// 每帧步长
	static double step = 0.6;

	// 两次循环停顿帧
	static final int pause = 150;

	static int pauseFrames = 0;

	static Thread thread;

	public static void main(String[] args) {

		final MatPlot3DMgr mgr = new MatPlot3DMgr();

		Random random = new Random();

		final ArrayList<double[][]> start = new ArrayList<double[][]>();
		final ArrayList<double[][]> target = new ArrayList<double[][]>();

		mgr.setDataInputType(MatPlot3DMgr.DATA_TYPE_MATRIX);

		mgr.setBeita(1.3);
		mgr.setSeeta(0.39);

		mgr.setScaleZ(5);
		// matPlot3DMgr.setScaleX(0.9);
		mgr.setScaleY(2);

		double[][] ds0 = new double[][] { { 4, 5, 7, 9, 11 }, { 3, 4, 6, 8, 10 }, { 2, 3, 5, 7, 9 },
				{ 1, 2, 4, 6, 8 } };

		int countInGroup = 4;

		for (int n = 0; n < countInGroup; n++) {

			double[][] ds = new double[4][5];

			for (int i = 0; i < ds0.length; i++) {
				for (int k = 0; k < ds0[0].length; k++) {
					ds[i][k] = ds0[i][k] + random.nextDouble();
				}
			}
			target.add(ds);

		}

		for (int n = 0; n < countInGroup; n++) {

			double[][] dss = new double[4][5];

			for (int i = 0; i < ds0.length; i++) {
				for (int k = 0; k < ds0[0].length; k++) {
					dss[i][k] = 0;
				}
			}

			start.add(dss);
		}

		mgr.getProcessor().setRulerLabelsX(new String[] { "2012", "2013", "2014", "2015", "2016" });
		mgr.getProcessor().setRulerLabelsY(new String[] { "4季度", "3季度", "2季度", "1季度" });
		
		mgr.getProcessor().setXName("X_年份");
		mgr.getProcessor().setYName("Y_季度");
		mgr.getProcessor().setZName("Z_指标");

		mgr.getProcessor().setCoordinateSysShowType(mgr.getProcessor().COORDINATE_SYS_STABLE);
		mgr.getProcessor().setCoordinateSysTransformationType(mgr.getProcessor().COORDINATE_RANGE_AUTO_FIT);

		mgr.show();

		thread = new Thread(new Runnable() {

//			@Override
			public void run() {

				int count = 0;

				List<double[][]> lastFrame = copy(start);

				while (true) {

					mgr.getProcessor().clear();

					List<double[][]> nextframe = nextFrame(start, lastFrame, target);

					for (int n = 0; n < nextframe.size(); n++) {

						mgr.addData("项目" + (n + 1), nextframe.get(n));

					}

					if (count <= 1) {
						mgr.fitScreem();
					}

					try {
						mgr.updateView(15);
					} catch (Exception e) {
						e.printStackTrace();
					}

					lastFrame = nextframe;

					count++;

					Thread.yield();
				}
			}

		});

		thread.start();
	}

	private static List<double[][]> copy(List<double[][]> src) {
		int column = src.size();
		int row = src.get(0).length;
		int group = src.get(0)[0].length;

		List<double[][]> rlist = new ArrayList<double[][]>();

		for (int i = 0; i < column; i++) {
			double[][] ds = new double[row][group];

			for (int j = 0; j < row; j++) {
				for (int k = 0; k < group; k++) {
					ds[j][k] = src.get(i)[j][k];
				}
			}

			rlist.add(ds);
		}

		return rlist;
	}

	private static List<double[][]> nextFrame(List<double[][]> start, List<double[][]> lastFrame,
			List<double[][]> target) {

		int row = target.get(0).length;
		int group = target.get(0)[0].length;

		int updateGroup = -1;

		for (int i = group - 1; i >= 0; i--) {
			for (int j = 0; j < target.size(); j++) {
				for (int k = 0; k < row; k++) {
					if (lastFrame.get(j)[k][i] >= target.get(j)[k][i]) {

					} else {
						updateGroup = i;
						break;
					}
				}
			}
		}

		// -----------------------------------

		// double step=0.12;

		if (updateGroup == -1) {
			pauseFrames++;

			if (pauseFrames < pause) {
				return lastFrame;
			} else {
				return copy(start);
			}

		} else {

			pauseFrames = 0;

			for (int j = 0; j < target.size(); j++) {
				for (int k = 0; k < row; k++) {
					if (lastFrame.get(j)[k][updateGroup] >= target.get(j)[k][updateGroup]) {
						continue;
					} else {
						double stepBuff = target.get(j)[k][updateGroup] / 25;

						if (lastFrame.get(j)[k][updateGroup] + stepBuff > target.get(j)[k][updateGroup]) {
							lastFrame.get(j)[k][updateGroup] = target.get(j)[k][updateGroup];
						} else {
							lastFrame.get(j)[k][updateGroup] += stepBuff;
						}
					}
				}
			}

			return lastFrame;
		}
	}
}
